using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Mic.Identity.Dto;
using System.Security.Claims;
using System.Text;
using Microsoft.IdentityModel.Tokens;
using Microsoft.IdentityModel.JsonWebTokens;
using System.IdentityModel.Tokens.Jwt;
using Mic.Identity.Service;

namespace Mic.Identity.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    [ApiController]
    //[Authorize]
    [Route("[controller]/[action]")]
    public class WeatherForecastController : ControllerBase
    {
        private static readonly string[] Summaries = new[]
        {
            "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
        };

        //UserManager<T>主要负责管理Identity的用户，SignInManager<T>主要负责Identity的认证过程
        private readonly UserManager<IdentityUser> userManager;//可以通过这个工具对密码进行加密  泛型为定义的用户模型

        private readonly SignInManager<IdentityUser> signInManager;//可以通过这个工具对密码进行加密  泛型为定义的用户模型

        private readonly ILogger<WeatherForecastController> _logger;

        private readonly IConfiguration _configuration;

        public ILazyTestService lazyTestService { get; set; }

        public WeatherForecastController(ILogger<WeatherForecastController> logger,
            UserManager<IdentityUser> userManager,
            SignInManager<IdentityUser> signInManager,
            IConfiguration configuration, ILazyTestService lazyTestService)
        {
            _logger = logger;
            this.userManager = userManager;
            this.signInManager = signInManager;
            this._configuration = configuration;
            this.lazyTestService = lazyTestService;
        }

        [HttpGet(Name = "GetWeatherForecast")]
        public IEnumerable<WeatherForecast> Get()
        {
            return Enumerable.Range(1, 5).Select(index => new WeatherForecast
            {
                Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
                TemperatureC = Random.Shared.Next(-20, 55),
                Summary = Summaries[Random.Shared.Next(Summaries.Length)]
            })
            .ToArray();
        }

        /// <summary>
        /// 退出
        /// </summary>
        /// <returns></returns>
        [Authorize("Producd.Select")]
        [HttpGet]
        public async Task<string> Logout()
        {
            await signInManager.SignOutAsync();
            return "";
        }

        /// <summary>
        /// test
        /// </summary>
        /// <returns></returns>
        //[Authorize(AuthenticationSchemes = "Bearer")]
        [HttpPost]
        public async Task<string> TestOne()
        {
            lazyTestService.LazyTest() ;
            var appUser = await userManager.GetUserAsync(HttpContext.User);
            var message = "Hello " + appUser?.UserName;
            return "xxxxx";
        }

        /// <summary>
        /// 用户注册
        /// </summary>
        /// <param name="registerDto">注册信息</param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost("register")]
        public async Task<IActionResult> Register([FromBody] RegisterDto registerDto)
        {
            //1 使用用户名创建用户对象
            var user = new IdentityUser()
            {
                UserName = registerDto.Email,
                Email = registerDto.Email
            };
            //2 hash密码，保存用户
            var result = await userManager.CreateAsync(user, registerDto.Password);//hash密码并连同用户模型对象 一起保存打数据库中
            //如果成功表示  用户创建成功并且保存起来了

            //不成功
            if (!result.Succeeded)
            {
                //返回400
                return BadRequest();
            }
            //3 return
            //成功  200
            return Ok();

        }

        [AllowAnonymous]//允许所有人访问
        [HttpPost("login")]
        public async Task<IActionResult> login([FromBody] LoginDto loginDto)
        {
            //1.进行信息认证
            //第三个参数表示我们不想持久化Cookie，第四个参数表示用户登录失败时是否锁定用户
            var loginResult = await signInManager.PasswordSignInAsync(loginDto.Email, loginDto.Password
                , false  //指示在关闭浏览器后登录 Cookie 是否应该保留的标志。
                , false//多次登录失败后 是否锁定账号
                );
            //退出登录
            //await signInManager.SignOutAsync();

            //判断是否验证成功
            if (!loginResult.Succeeded)
            {
                // 400
                return BadRequest();
            }
            else
            {
                //获取用户信息
                //var appUser = await userManager.FindByEmailAsync(loginDto.Email);
                var user = await userManager.FindByNameAsync(loginDto.Email);
                return Ok("");
            }


            //  //2.创建JWT  Token
            //  //header   singningAlgorithm储存编码算法
            //  var singningAlgorithm = SecurityAlgorithms.HmacSha256;
            //  //payload   需要用到的数据
            //  var claims = new List<Claim> { 
            // // sub ==jwt的ID    
            // //等同于  Sub:fake_user_id
            //  new Claim(System.IdentityModel.Tokens.Jwt.JwtRegisteredClaimNames.Sub,user.Id)
            //// new Claim(ClaimTypes.Role,"Admin")//角色信息

            // };
            //  //获取用户角色
            //  var roleNames = await userManager.GetRolesAsync(user);
            //  //遍历角色  一个用户可能有多个角色
            //  foreach (var roleName in roleNames)
            //  {
            //      var roleClaim = new Claim(ClaimTypes.Role, roleName);
            //      claims.Add(roleClaim);
            //  }

            //  //signature   数字签名   需要用到私钥
            //  //私钥一般放在配置文件中  私钥是自定义的  想写什么写什么

            //  //使用utf进行编码
            //  var secretByte = Encoding.UTF8.GetBytes("R2XMnd6TQdYRUmR0cCfL9fk651Fb3kDI");
            //  //使用非对称算法 对私钥加密
            //  var signingkey = new SymmetricSecurityKey(secretByte);
            //  //通过256验证非对称加密的私钥
            //  var signingCredentials = new SigningCredentials(signingkey, singningAlgorithm);

            //  //创建token
            //  var token = new JwtSecurityToken(
            //      issuer:  "api",//谁发布的TOken
            //      audience: "api",//token发布给谁
            // claims,//payload数据
            // notBefore: DateTime.UtcNow,//发布时间
            // expires: DateTime.UtcNow.AddDays(1),//有效时间
            // signingCredentials//数字签名
            //      );

            //  //以字符串形式 输出Token
            //  var tokenStr = new JwtSecurityTokenHandler().WriteToken(token);

            //  //3.返回jwt字符串

            //  return Ok(tokenStr);
        }


    }
}
